#ifndef _v2_H_
#define _v2_H_


class v2
{
public:
    // member functions
	void Clear() { Set(0.0f, 0.0f); };
	v2 Set(float fX, float fY) { x=fX; y=fY; return *this; };
  inline v2& operator=(const v2 &V);
  inline v2 operator+(const v2 &V) const;
  inline v2 operator-(const v2 &V) const;
  inline v2 operator*(float f) const;
  float Magnitude() const;
  inline float MagnitudeSquared() const;
  inline float Normalize();    // returns original length
	inline v2 Lerp(const v2 &V, float fBlend) const;
	inline float Dot(const v2 &V) const;
	inline bool IsZero(float fEpsilon=0.0f);
	inline bool IsOne(float fEpsilon=0.001f);

  // a sort of constructor
  static v2 Make(float x, float y) { v2 v; v.Set(x, y); return v; };

  // members
	float x;
	float y;
};


#include "OMath.h"

v2& v2::operator=(const v2 &V)
{
	x=V.x;
	y=V.y;

	return *this;
}


v2 v2::operator+(const v2 &V) const
{
	v2 R;

	R.x=x+V.x;
	R.y=y+V.y;

	return R;
}


v2 v2::operator-(const v2 &V) const
{
	v2 R;

	R.x=x-V.x;
	R.y=y-V.y;

	return R;
}


v2 v2::operator*(float f) const
{
	v2 R;

	R.x=x*f;
	R.y=y*f;

	return R;
}


float v2::MagnitudeSquared() const
{
	return x*x+y*y;
}


float v2::Normalize()
{
	float fMag;
	float fOOMag;

	fMag=Magnitude();
	if(fMag)
	{
		fOOMag=1.0f/fMag;
		x*=fOOMag;
		y*=fOOMag;
	}

  return fMag;
}


v2 v2::Lerp(const v2 &V, float fBlend) const
{
	return *this + (V - *this) * fBlend;
}


float v2::Dot(const v2 &V) const
{
	return x*V.x+y*V.y;
}


bool v2::IsZero(float fEpsilon)
{
	float fEE;
	float fMM;

	fEE=fEpsilon*fEpsilon;
	fMM=v2::MagnitudeSquared();

	return fMM<=fEE;
}


bool v2::IsOne(float fEpsilon)
{
	float fEE;
	float fMM;

	fEE=fEpsilon*fEpsilon;
	fMM=v2::MagnitudeSquared();

	return fMM>=1.0f-fEE && fMM<=1.0f+fEE;
}


#endif
